package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.DistanceUtils;
import com.tanhua.common.utils.RelativeDateFormat;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.QuanZiApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.UserLocationApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.dubbo.enums.CommentType;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.Publish;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Visitors;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.dubbo.vo.UserLocationVo;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.QuanZiVo;
import com.tanhua.server.vo.VisitorsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class QuanZiService {

    @DubboReference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private UserService userService;

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @DubboReference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    private QuanziMQService quanziMQService;

    @DubboReference(version = "1.0.0")
    private UserLocationApi userLocationApi;



    /**
     * 查询好友动态
     *
     * @param page
     * @param pageSize
     * @return
     */
    public Object queryPublishList(Integer page, Integer pageSize) {
        Long userId = UserThreadLocal.get();

        PageResult pageResult = new PageResult();
        pageResult.setPagesize(pageSize);
        pageResult.setPage(page);

        //查询好友的动态
        PageInfo<Publish> pageInfo = this.quanZiApi.queryPublishList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return pageResult;
        }

        //封装成QuanZiVo列表

        //查询动态发布人的用户信息列表
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));

        List<QuanZiVo> quanZiVoList = new ArrayList<>();

        for (Publish record : records) {
            String publishId = record.getId().toString();
            QuanZiVo quanZiVo = BeanUtil.toBeanIgnoreError(record, QuanZiVo.class);

            //获取当前用户的经纬度
            UserLocationVo userLocationVo1 = this.userLocationApi.queryByUserId(userId);
            Double longitude1 = userLocationVo1.getLongitude();
            Double latitude1 = userLocationVo1.getLatitude();
            //获取动态发布人的经纬度
            UserLocationVo userLocationVo2 = this.userLocationApi.queryByUserId(record.getUserId());
            Double longitude2 = userLocationVo2.getLongitude();
            Double latitude2 = userLocationVo2.getLatitude();
            //计算两人的距离
            double distance = DistanceUtils.getDistance(longitude1, latitude1, longitude2, latitude2);
            BigDecimal bigDecimal = new BigDecimal(distance).setScale(0, BigDecimal.ROUND_HALF_UP);
            String distanceStr = String.valueOf(bigDecimal);

            //获取发布人的地址
            String address = userLocationVo2.getAddress();
            quanZiVo.setDistance(distanceStr+"公里"+"  " + "(" + address + ")"); //TODO 距离（完成）
            //TODO 距离（完成）
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(record.getCreated()))); //发布时间 如: 10分钟前
            quanZiVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(publishId))); //点赞数
            quanZiVo.setCommentCount(Convert.toInt(this.quanZiApi.queryCommentCount(publishId,CommentType.COMMENT))); //TODO 评论数
            quanZiVo.setLoveCount(Convert.toInt(this.quanZiApi.queryLoveCount(publishId))); //TODO 喜欢数
            quanZiVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, publishId) ? 1 : 0); //是否点赞（1是，0否）
            quanZiVo.setHasLoved(this.quanZiApi.queryUserIsLove(userId,publishId)? 1 : 0); //TODO 是否喜欢（1是，0否）否）

            //填充用户信息
            UserInfo userInfo = userInfoMap.get(record.getUserId());
            BeanUtil.copyProperties(userInfo, quanZiVo,"id");
            quanZiVo.setGender(userInfo.getSex().name().toLowerCase());

            quanZiVoList.add(quanZiVo);
        }

        pageResult.setItems(quanZiVoList);
        return pageResult;
    }

    // com.tanhua.server.service.QuanZiService

    /**
     * 发布动态
     *
     * @param textContent
     * @param location
     * @param latitude
     * @param longitude
     * @param multipartFile
     * @return
     */
    public Object savePublish(String textContent, String location, String latitude,
                              String longitude, MultipartFile[] multipartFile) {

        Publish publish = new Publish();
        publish.setUserId(UserThreadLocal.get());
        publish.setText(textContent);
        publish.setLocationName(location);
        publish.setLongitude(longitude);
        publish.setLatitude(latitude);
        publish.setMedias(new ArrayList<>());

        //上传图片
        if(ArrayUtil.isNotEmpty(multipartFile)){
            for (MultipartFile file : multipartFile) {
                PicUploadResult uploadResult = this.picUploadService.upload(file);
                if (StrUtil.isNotEmpty(uploadResult.getName())) {
                    publish.getMedias().add(uploadResult.getName());
                }
            }
        }

        String result = this.quanZiApi.savePublish(publish);
        if (StrUtil.isNotEmpty(result)) {
            return null;
        }

        return ErrorResult.builder().errCode("500")
                .errMessage("发布动态失败！").build();
    }


    /**
     * 查询推荐动态
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryRecommendPublish(Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();
        PageInfo<Publish> pageInfo = this.quanZiApi.queryRecommendPublishList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();

        if (CollUtil.isEmpty(records)) {
            //TODO 没有数据，给出默认(完成)
            for (int i = 0; i < 10; i++) {
                String medias1 = "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/6/CL-3.jpg";
                String medias2 = "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/6/1.jpg";
                ArrayList<String> medias = new ArrayList<>();
                medias.add(medias1);
                medias.add(medias2);
                Publish publish = new Publish();
                publish.setId(ObjectId.get());
                publish.setPid(2900L);
                publish.setUserId(50L);
                publish.setText("这世上没有人是不可或缺的，没有什么是不可替代的。");
                publish.setMedias(medias);
                publish.setSeeType(1);
                publish.setLongitude("116.350426");
                publish.setLatitude("40.066355");
                publish.setLocationName("中国北京市昌平区建材城西路16号");
                publish.setCreated(1605260236033L);
                //添加默认数据
                records.add(publish);
            }

        }

        pageResult.setItems(this.fillQuanZiVo(records));
        return pageResult;
    }

    private List<QuanZiVo> fillQuanZiVo(List<Publish> records) {
        //封装成QuanZiVo列表
        //查询动态发布人的用户信息列表

        Long userId = UserThreadLocal.get();

        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));

        List<QuanZiVo> quanZiVoList = new ArrayList<>();

        for (Publish record : records) {
            String publishId = record.getId().toString();
            QuanZiVo quanZiVo = BeanUtil.toBeanIgnoreError(record, QuanZiVo.class);

            //获取当前用户的经纬度
            UserLocationVo userLocationVo1 = this.userLocationApi.queryByUserId(userId);
            Double longitude1 = userLocationVo1.getLongitude();
            Double latitude1 = userLocationVo1.getLatitude();
            //获取动态发布人的经纬度
            UserLocationVo userLocationVo2 = this.userLocationApi.queryByUserId(record.getUserId());
            Double longitude2 = userLocationVo2.getLongitude();
            Double latitude2 = userLocationVo2.getLatitude();
            //计算两人的距离
            double distance = DistanceUtils.getDistance(longitude1, latitude1, longitude2, latitude2);
            BigDecimal bigDecimal = new BigDecimal(distance).setScale(0, BigDecimal.ROUND_HALF_UP);
            String distanceStr = String.valueOf(bigDecimal);

            //获取发布人的地址
            String address = userLocationVo2.getAddress();
            quanZiVo.setDistance(distanceStr+"公里"+"  " + "(" + address + ")"); //TODO 距离（完成）

            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(record.getCreated()))); //发布时间 如: 10分钟前
            quanZiVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(publishId))); //TODO 点赞数
            quanZiVo.setCommentCount(Convert.toInt(this.quanZiApi.queryCommentCount(publishId,CommentType.COMMENT))); //TODO 评论数
            quanZiVo.setLoveCount(Convert.toInt(this.quanZiApi.queryLoveCount(publishId))); //TODO 喜欢数
            quanZiVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, publishId) ? 1 : 0); //TODO 是否点赞（1是，0否）
            quanZiVo.setHasLoved(this.quanZiApi.queryUserIsLove(userId,publishId)? 1 : 0); //TODO 是否喜欢（1是，0否）

            //填充用户信息
            UserInfo userInfo = userInfoMap.get(record.getUserId());
            BeanUtil.copyProperties(userInfo, quanZiVo, "id");
            quanZiVo.setGender(userInfo.getSex().name().toLowerCase());

            quanZiVoList.add(quanZiVo);
        }
        return quanZiVoList;
    }

    public Long likeComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //点赞
        Boolean result = this.quanZiApi.likeComment(userId, publishId);
        if (result) {
            //发消息
            this.quanziMQService.likePublishMsg(publishId);
            //查询点赞数
            return this.quanZiApi.queryLikeCount(publishId);
        }


        return 0L;
    }

    public Long disLikeComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //取消点赞
        Boolean result = this.quanZiApi.disLikeComment(userId, publishId);
        if (result) {

            //发消息
            this.quanziMQService.disLikePublishMsg(publishId);

            //查询点赞数
            return this.quanZiApi.queryLikeCount(publishId);
        }
        return 0L;
    }

    public Long loveComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //喜欢
        Boolean result = this.quanZiApi.loveComment(userId, publishId);
        if (result) {

            //发消息
            this.quanziMQService.disLikePublishMsg(publishId);
            //查询喜欢数
            return this.quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    public Long disLoveComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //取消喜欢
        Boolean result = this.quanZiApi.disLoveComment(userId, publishId);
        if (result) {

            //发消息
            this.quanziMQService.disLovePublishMsg(publishId);
            //查询喜欢数
            return this.quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }


    public QuanZiVo queryById(String publishId) {
        Publish publish = this.quanZiApi.queryPublishById(publishId);
        if(null == publish){
            return null;
        }

        //发消息
        this.quanziMQService.queryPublishMsg(publishId);

        return this.fillPublishList(Arrays.asList(publish));
    }

    private QuanZiVo fillPublishList(List<Publish> records) {
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));
        QuanZiVo quanZiVo = new QuanZiVo();
        for (Publish record : records) {
            quanZiVo = BeanUtil.toBeanIgnoreError(record, QuanZiVo.class);
            //填充用户信息
            UserInfo userInfo = userInfoMap.get(record.getUserId());
            BeanUtil.copyProperties(userInfo, quanZiVo, "id");
            quanZiVo.setGender(userInfo.getSex().name().toLowerCase());
        }

        return quanZiVo;
    }


    /**
     * 自己的所有动态
     */
    public PageResult queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);


        Long count = this.quanZiApi.queryPublishCount(userId);
        pageResult.setCounts(count.intValue()); //TODO 数量(完成)

        PageInfo<Publish> pageInfo = this.quanZiApi.queryAlbumList(userId, page, pageSize);
        //显示动态数量
        pageResult.setCounts(pageInfo.getTotal());
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return pageResult;
        }

        pageResult.setItems(this.fillQuanZiVo(records));
        return pageResult;
    }


    /**
     * 查询评论列表
     *
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryCommentList(String publishId, Integer page, Integer pageSize) {

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();

        //查询评论列表数据
        PageInfo<Comment> pageInfo = this.quanZiApi.queryCommentList(publishId, page, pageSize);
        List<Comment> records = pageInfo.getRecords();
        if(CollUtil.isEmpty(records)){
            return pageResult;
        }

        //查询用户信息
        List<Object> userIdList = CollUtil.getFieldValues(records, "userId");
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(userIdList);

        List<CommentVo> result = new ArrayList<>();
        for (Comment record : records) {
            CommentVo commentVo = new CommentVo();
            commentVo.setContent(record.getContent());
            commentVo.setId(record.getId().toHexString());
            commentVo.setCreateDate(DateUtil.format(new Date(record.getCreated()), "HH:mm"));
            //是否点赞
            commentVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, commentVo.getId()) ? 1 : 0);
            //点赞数
            commentVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(commentVo.getId())));

            for (UserInfo userInfo : userInfoList) {
                if(ObjectUtil.equals(record.getUserId(), userInfo.getUserId())){
                    commentVo.setAvatar(userInfo.getLogo());
                    commentVo.setNickname(userInfo.getNickName());
                    break;
                }
            }
            result.add(commentVo);
        }
        pageResult.setItems(result);
        return pageResult;
    }

    /**
     * 发表评论
     * @param publishId
     * @param content
     * @return
     */
    public Boolean saveComments(String publishId, String content) {
        return this.quanZiApi.saveComment(UserThreadLocal.get(), publishId, content);
    }


    public List<VisitorsVo> queryVisitorsList() {
        Long userId = UserThreadLocal.get();
        List<Visitors> visitorsList = this.visitorsApi.queryMyVisitor(userId);
        if (CollUtil.isEmpty(visitorsList)) {
            return Collections.emptyList();
        }

        //访客用户信息
      /*   Map<Long, UserInfo> visitorUserIdMap = this.userInfoApi
                 .queryMapByUserIdList(CollUtil.getFieldValues(visitorsList, "visitorUserId"));

         List<VisitorsVo> result = new ArrayList<>();
         for (Visitors visitors : visitorsList) {
             UserInfo userInfo = visitorUserIdMap.get(visitors.getVisitorUserId());
             VisitorsVo visitorsVo = BeanUtil.toBeanIgnoreError(userInfo, VisitorsVo.class);
             visitorsVo.setGender(userInfo.getSex().name().toLowerCase());

             result.add(visitorsVo);
         }
         return result;*/

        return this.userInfoApi
                .queryByUserIdList(CollUtil.getFieldValues(visitorsList, "visitorUserId"))
                .stream().map(userInfo -> {
                    VisitorsVo visitorsVo = BeanUtil.toBeanIgnoreError(userInfo, VisitorsVo.class);
                    visitorsVo.setGender(userInfo.getSex().name().toLowerCase());
                    return visitorsVo;
                }).collect(Collectors.toList());

    }

}
